﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading;
using ICSharpCode.SharpZipLib.Zip;

namespace SvnLightClient
{
    public partial class Main : Form
    {
        private Configuration _configuration;

        public Main()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            this.lblDescription.Text = Properties.Settings.Default.Description;
            _configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            InitTextFromConfig();
            this.txtZipPasswd.DataBindings.Add("Enabled", this.chkZip, "Checked");
        }

        private void btnConfig_Click(object sender, EventArgs e)
        {
            var config = new Config();
            config.AppConfiguration = _configuration;
            config.ShowDialog();
            _configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            InitTextFromConfig();
        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
            var baseDir = this.txtRoot.Text;

            if (!string.IsNullOrEmpty(baseDir))
                this.folderBrowserDialog1.SelectedPath = baseDir;
            else
                this.folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
            var ret = this.folderBrowserDialog1.ShowDialog();
            if (ret == System.Windows.Forms.DialogResult.OK)
                baseDir = this.folderBrowserDialog1.SelectedPath;
            this.txtRoot.Text = baseDir;

            _configuration.AppSettings.Settings.Remove("BaseDir");
            _configuration.AppSettings.Settings.Add("BaseDir", this.txtRoot.Text);
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            _configuration.Save();
        }
        private void btnGet_Click(object sender, EventArgs e)
        {
            GetAsync(this.rtbSvnItemList.Lines);    
        }

        private void InitTextFromConfig()
        {
            this.txtRoot.Text = _configuration.AppSettings.Settings["BaseDir"].Value;
            this.txtZipPasswd.Text = _configuration.AppSettings.Settings["ZipPassword"].Value;
        }

        private void GetAsync(object param)
        {
            rtbSvnItemList.ForeColor = Color.Black;
            var workThread = new Thread((object lines) => {

                Action disabledBtnGet = () => btnGet.Enabled = false;
                this.Invoke(disabledBtnGet);
                var paths = lines as string[];
                var serverUrl = _configuration.AppSettings.Settings["ServerUrl"].Value;
                var userName = _configuration.AppSettings.Settings["UserName"].Value;
                var password = _configuration.AppSettings.Settings["Password"].Value;
                var workDir = Path.Combine(this.txtRoot.Text, DateTime.Now.ToString("yyyyMMddHHmmss"));
                var errorTexts = "";

                Action<int, Color> updateRichBoxLine = (index, color) =>
                {
                    int first = rtbSvnItemList.GetFirstCharIndexFromLine(index);
                    int last = rtbSvnItemList.Text.Length - 1;
                    rtbSvnItemList.Select(first, rtbSvnItemList.Lines[index].Length);
                    rtbSvnItemList.SelectionColor = color;
                    //richTextBox1.Select(last, 0);
                };

                using (var client = new SvnLightClient()
                {
                    UserName = userName,
                    Password = password,
                    ServerUrl = serverUrl,
                    WorkDirectory = workDir
                })
                {
                    client.GetProcessing += p => {
                        Action<string> updateProcessInfo = (msg) => this.lblProcessInfoContent.Text = msg;
                        this.Invoke(updateProcessInfo, Path.GetFileName(p));
                    };

                    for (int i = 0; i < paths.Length; i++)
                    {
                        try
                        {
                            client.Get(paths[i]);
                            this.Invoke(updateRichBoxLine, i, Color.Green);
                        }
                        catch (Exception ex)
                        {
                            errorTexts += ex.Message + Environment.NewLine;
                            this.Invoke(updateRichBoxLine, i, Color.Red);
                        }   
                    }
                }
                if (!string.IsNullOrEmpty(errorTexts))
                {
                    Action showError = () => { MessageBox.Show(errorTexts, "SvnLightClient", MessageBoxButtons.OK, MessageBoxIcon.Error); };
                    this.Invoke(showError);
                }
                else
                {
                    var zipFileName = "";
                    if (this.chkZip.Checked)
                    {
                        zipFileName = Path.Combine(Path.GetDirectoryName(workDir), Path.GetFileName(workDir) + ".zip");
                        Utils.ZipDirectory(zipFileName, workDir, txtZipPasswd.Text);
                    }

                    if (this.chkOpenFolder.Checked)
                        Utils.OpenFolder(this.chkZip.Checked ? zipFileName : workDir);
                }
                Action enabledBtnGet = () => btnGet.Enabled = true;
                this.Invoke(enabledBtnGet);
            });
            workThread.Start(param);
        }

    }
}
